package cn.psvmc.cxzapi.service.system;

import cn.psvmc.cxzapi.config.ConfigKey;
import cn.psvmc.cxzapi.constant.GlobalConstant;
import cn.psvmc.cxzapi.enums.ResultCode;
import cn.psvmc.cxzapi.exception.ServiceException;
import cn.psvmc.cxzapi.mapper.customer.*;
import cn.psvmc.cxzapi.mapper.goods.TGoodsSpecsMapper;
import cn.psvmc.cxzapi.mapper.order.*;
import cn.psvmc.cxzapi.mapper.store.*;
import cn.psvmc.cxzapi.mapper.system.TPlatformSetMapper;
import cn.psvmc.cxzapi.mapper.system.TUserMapper;
import cn.psvmc.cxzapi.model.common.SearchEntity;
import cn.psvmc.cxzapi.model.customer.*;
import cn.psvmc.cxzapi.model.goods.TGoodsSpecsRent;
import cn.psvmc.cxzapi.model.order.*;
import cn.psvmc.cxzapi.model.store.*;
import cn.psvmc.cxzapi.model.system.TRole;
import cn.psvmc.cxzapi.model.system.TUser;
import cn.psvmc.cxzapi.model.ticket.TTicket;
import cn.psvmc.cxzapi.service.alipay.AlipayCreate;
import cn.psvmc.cxzapi.service.eqb.EqbService;
import cn.psvmc.cxzapi.service.order.TOrderLogService;
import cn.psvmc.cxzapi.util.*;
import cn.psvmc.cxzapi.util.delivery.DbAPIService;
import cn.psvmc.cxzapi.util.delivery.SfAPIService;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.domain.AlipayTradeCreateModel;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.response.*;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author ywx
 * Date 2024/8/20 14:40
 **/
@Service
@Slf4j
public class ServiceUtil {
    @Resource
    private HttpServletRequest request;
    @Resource
    private TUserMapper tUserMapper;
    @Resource
    private TCustomerMapper customerMapper;
    @Resource
    private TPlatformSetMapper platformSetMapper;
    @Resource
    private TStoreMapper storeMapper;
    @Resource
    private TCustomerAuthMapper customerAuthMapper;
    @Resource
    private TOrderDeliveryMapper orderDeliveryMapper;
    @Resource
    private TOrderDeliveryRecordMapper orderDeliveryRecordMapper;
    @Resource
    private TOrderMapper orderMapper;
    @Resource
    private TOrderRecordMapper orderRecordMapper;
    @Resource
    private TOrderLogService orderLogService;
    @Resource
    private TGoodsSpecsMapper goodsSpecsMapper;
    @Resource
    private TOrderBillMapper orderBillMapper;
    @Resource
    private TOrderContractMapper orderContractMapper;
    @Resource
    private TAccountBillMapper accountBillMapper;
    @Resource
    private TAccountMapper accountMapper;
    @Resource
    private EqbService eqbService;
    @Resource
    private TStoreDetailMapper tStoreDetailMapper;
    @Resource
    private TCouponMapper tCouponMapper;
    @Resource
    private TCustomerCouponMapper tCustomerCouponMapper;
    @Resource
    private TOrderCouponMapper tOrderCouponMapper;
    @Resource
    private TCouponCodeMapper tCouponCodeMapper;

    //设置商家id
    public void setStoreId(SearchEntity entity) {
        int userid = request.getIntHeader(GlobalConstant.USRID);
        ToolUtils.checkUserId(userid);
        TUser tUser = tUserMapper.selectById(userid);
        if (tUser == null) {
            throw new ServiceException(ResultCode.NO_USER_ERROR.getMsg());
        }
        entity.setStoreid(tUser.getStoreid());
    }

    //设置商家id
    public void setStoreId(TRole tRole) {
        int userid = request.getIntHeader(GlobalConstant.USRID);
        TUser tUser = tUserMapper.selectById(userid);
        if (tUser == null) {
            throw new ServiceException(ResultCode.NO_USER_ERROR.getMsg());
        }
        tRole.setStoreid(tUser.getStoreid());
    }

    //设置用户id
    public void setUserId(SearchEntity entity) {
        int userid = request.getIntHeader(GlobalConstant.USRID);
        ToolUtils.checkUserId(userid);
        entity.setUserid(userid);
    }

    //获取商家id
    public Integer getStoreId() {
        int userid = request.getIntHeader(GlobalConstant.USRID);
        ToolUtils.checkUserId(userid);
        TUser tUser = tUserMapper.selectById(userid);
        if (tUser == null) {
            throw new ServiceException(ResultCode.NO_USER_ERROR.getMsg());
        }
        return tUser.getStoreid();
    }

    //获取用户名
    public String getUserName() {
        int userid = request.getIntHeader(GlobalConstant.USRID);
        ToolUtils.checkUserId(userid);
        TUser tUser = tUserMapper.selectById(userid);
        if (tUser == null) {
            throw new ServiceException(ResultCode.NO_USER_ERROR.getMsg());
        }
        return tUser.getUsername();
    }

    //获取用户名
    public String getUserNameById(int userid) {
        TUser tUser = tUserMapper.selectById(userid);
        if (tUser == null) {
            throw new ServiceException(ResultCode.NO_USER_ERROR.getMsg());
        }
        return tUser.getUsername();
    }

    //获取客户id
    public Integer getCustomerId() {
        int userid = request.getIntHeader(GlobalConstant.USRID);
        ToolUtils.checkUserId(userid);
        TCustomer tCustomer = customerMapper.selectById(userid);
        if (tCustomer == null) {
            throw new ServiceException(ResultCode.NO_USER_ERROR.getMsg());
        }
        return userid;
    }

    //根据支付宝id获取客户id
    public Integer getCustomerId(String openid) {
        return customerMapper.getCustomerIdByOpenid(openid);
    }

    //获取客户id，不检查用户是否存在
    public Integer getCustomerIdNoCheck() {
        return request.getIntHeader(GlobalConstant.USRID);
    }

    //获取客户信息，不检查用户是否存在
    public TCustomer getCustomerNoCheck(int customerId) {
        return customerMapper.selectById(customerId);
    }

    //获取客户信息
    public TCustomer getCustomer() {
        int userid = request.getIntHeader(GlobalConstant.USRID);
        ToolUtils.checkUserId(userid);
        TCustomer tCustomer = customerMapper.selectById(userid);
        if (tCustomer == null) {
            throw new ServiceException(ResultCode.NO_USER_ERROR.getMsg());
        }
        return tCustomer;
    }

    //获取用户id
    public Integer getUserId() {
        int userid = request.getIntHeader(GlobalConstant.USRID);
        ToolUtils.checkUserId(userid);
        return userid;
    }

    //获取最接近的租金
    public TGoodsSpecsRent findClosestRent(List<TGoodsSpecsRent> specsList, int day) {
        TGoodsSpecsRent closestRent = null;
        TGoodsSpecsRent smallestRent = null;
        int closestDayDifference = Integer.MAX_VALUE;
        int smallestDay = Integer.MAX_VALUE;

        for (TGoodsSpecsRent spec : specsList) {
            int specDay = spec.getDay();
            if (specDay <= day && (day - specDay) < closestDayDifference) {
                closestDayDifference = day - specDay;
                closestRent = spec;
            }
            if (specDay < smallestDay) {
                smallestDay = specDay;
                smallestRent = spec;
            }
        }

        // 如果没有找到比day小的方案，取最小的day的rent
        if (closestRent == null) {
            closestRent = smallestRent;
        }

        return closestRent;
    }

    //根据天数计算租期（30天为一个租期）
    public static int calculateLeasePeriods(int day) {
        // 计算整除的部分
        int fullPeriods = day / 30;
        // 计算余数
        int remainder = day % 30;
        // 如果有余数，则需要额外的一个租期
        if (remainder > 0) {
            return fullPeriods + 1;
        } else {
            return fullPeriods;
        }
    }

    //校验工单是否存在且未关闭
    public static void checkTicket(TTicket ticket) {
        if (ticket == null) {
            throw new ServiceException("工单不存在！");
        } else if (ticket.getStatus().equals(1)) {
            throw new ServiceException("工单已关闭！");
        }
    }

    /**
     * @Description 获取临时访问凭证
     * @Date 2024/9/8 18:07
     * @Author YWX
     * @Param []
     * @Return java.util.Map<java.lang.String, java.lang.String>
     **/
    public static Map<String, String> getSts() {
        Map<String, String> map = new HashMap<>();
        // STS服务接入点，例如sts.cn-hangzhou.aliyuncs.com。您可以通过公网或者VPC接入STS服务。
        String endpoint = ConfigKey.stsEndpoint;
        // 从环境变量中获取步骤1生成的RAM用户的访问密钥（AccessKey ID和AccessKey Secret）。
        String accessKeyId = ConfigKey.stsAccessKeyId;
        String accessKeySecret = ConfigKey.stsAccessKeySecret;
        // 从环境变量中获取步骤3生成的RAM角色的RamRoleArn。
        String roleArn = ConfigKey.arn;
        // 自定义角色会话名称，用来区分不同的令牌，例如可填写为SessionTest。
        String roleSessionName = ConfigKey.sessionName;
        // 临时访问凭证将获得角色拥有的所有权限。
        String policy = null;
        // 临时访问凭证的有效时间，单位为秒。最小值为900，最大值以当前角色设定的最大会话时间为准。当前角色最大会话时间取值范围为3600秒~43200秒，默认值为3600秒。
        // 在上传大文件或者其他较耗时的使用场景中，建议合理设置临时访问凭证的有效时间，确保在完成目标任务前无需反复调用STS服务以获取临时访问凭证。
        Long durationSeconds = 3600L;
        try {
            // 发起STS请求所在的地域。建议保留默认值，默认值为空字符串（""）。
            String regionId = "";
            // 添加endpoint。适用于Java SDK 3.12.0及以上版本。
            //DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
            // 添加endpoint。适用于Java SDK 3.12.0以下版本。
            DefaultProfile.addEndpoint("", regionId, "Sts", endpoint);
            // 构造default profile。
            IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            // 构造client。
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            // 适用于Java SDK 3.12.0及以上版本。
            //request.setSysMethod(MethodType.POST);
            // 适用于Java SDK 3.12.0以下版本。
            request.setMethod(MethodType.POST);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(null);
            request.setDurationSeconds(durationSeconds);
            final AssumeRoleResponse response = client.getAcsResponse(request);
            map.put("expiration", response.getCredentials().getExpiration());
            map.put("accessKeyId", response.getCredentials().getAccessKeyId());
            map.put("accessKeySecret", response.getCredentials().getAccessKeySecret());
            map.put("securityToken", response.getCredentials().getSecurityToken());
            map.put("requestId", response.getRequestId());
            return map;
        } catch (ClientException e) {
            ServiceUtil.log.error("获取临时访问凭证出错: {}", e.getMessage());
            throw new ServiceException("获取临时访问凭证出错: " + e.getMessage());
        }
    }

    //获取支付宝交易号
    public static String getTradeNo(String transactionId, Object totalAmount, String subject, String body
            , String openid, GoodsDetail gd) {
        //统一收单交易创建
        AlipayTradeCreateModel model = new AlipayTradeCreateModel();
        model.setOutTradeNo(transactionId);
        model.setTotalAmount(ToolUtils.objToString(totalAmount));
        model.setSubject(subject);
        model.setBuyerOpenId(openid);
        model.setBody("小程序：" + ConfigKey.appName + "；" + body);
        model.setProductCode("JSAPI_PAY");
        model.setGoodsDetail(Arrays.asList(gd));
        AlipayTradeCreateResponse response = AlipayCreate.AlipayTradeCreate(model);
        return response.getTradeNo();
    }

    //定时任务获取支付宝交易号
    public String getTradeNo(String transactionId, Object totalAmount, String subject, String body, Integer customerid, GoodsDetail gd) {
        return ServiceUtil.getTradeNo(transactionId, totalAmount, subject, body, getOpenIdByCustomerId(customerid), gd);
    }

    //获取支付宝交易号（商家）
    public String getTradeNoForStore(String transactionId, Object totalAmount, String subject, Integer customerid) {
        //统一收单交易创建
        AlipayTradeCreateModel model = new AlipayTradeCreateModel();
        model.setOutTradeNo(transactionId);
        model.setTotalAmount(ToolUtils.objToString(totalAmount));
        model.setSubject(subject);
        TCustomer customer = customerMapper.selectById(customerid);
        String openid = customer.getOpenid();
        String userid = customer.getUserid();
        if (ToolUtils.isNotEmpty(openid)) {
            model.setBuyerOpenId(openid);
        } else if (ToolUtils.isNotEmpty(userid)) {
            model.setBuyerId(userid);
        }
        model.setProductCode("JSAPI_PAY");
        AlipayTradeCreateResponse response = AlipayCreate.AlipayTradeCreate(model);
        ServiceUtil.log.info("商家支付宝下单返回结果：{}", JSON.toJSONString(response));
        return response.getTradeNo();
    }

    /**
     * @Description 生成授权书
     * @Date 2024/10/4 22:03
     * @Author YWX
     * @Param [authPeople]
     * @Return java.lang.String
     **/
    public String upPdfToOss(Object authPeople) {
        return uploadPdfToOss(FileUtils.generateHtml(ToolUtils.objToString(authPeople)), 1);
    }

    /**
     * @Description 上传PDF到OSS
     * @Date 2024/10/4 22:03
     * @Author YWX
     * @Param [tempHtmlPath]
     * @Return java.lang.String
     **/
    public String uploadPdfToOss(String tempHtmlPath, Integer type) {
        String filename = tempHtmlPath.substring(tempHtmlPath.lastIndexOf("/") + 1, tempHtmlPath.lastIndexOf("."));
        String pdfPath = ConfigKey.pdfpath + filename + ".pdf";
        StringBuilder cmd = new StringBuilder();
        cmd.append(ConfigKey.topdfpath);
        cmd.append(" --disable-smart-shrinking ");//禁用智能收缩
        cmd.append(tempHtmlPath);
        cmd.append(" ").append(pdfPath);

        int exitCode;
        try {
            ServiceUtil.log.info("开始执行命令：{}", cmd);
            Process process = Runtime.getRuntime().exec(cmd.toString());
            exitCode = process.waitFor();
        } catch (IOException | InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Failed to wait for wkhtmltopdf process", e);
        }

        if (exitCode == 0) {
            // 上传PDF到OSS
            FileUtils.deleteFile(tempHtmlPath);//删除本地文件
            String upload;
            if (type.equals(1)) {//授权书
                upload = OssService.upload(pdfPath);
                FileUtils.deleteFile(pdfPath);//删除本地文件
                return upload;
            } else {//租赁合同
                return pdfPath;
            }
        } else {
            ServiceUtil.log.error("上传PDF到OSS失败:{}", exitCode);
            throw new ServiceException("上传PDF到OSS失败！");
        }
    }

    //获取风险报告
    public String getReportContent(String realName, String identNumber, String phone) {
        if (ToolUtils.isEmpty(realName) || ToolUtils.isEmpty(identNumber) || ToolUtils.isEmpty(phone)) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("name", realName);
        map.put("ident_number", identNumber);
        map.put("phone", phone);
        String ossPath = upPdfToOss(realName);
        map.put("oss_path", ossPath);
        String riskReport = HttpUtil.getRiskReport(map);
        Map<String, Object> result = JSON.parseObject(riskReport, Map.class);
        if (result == null) {
            ServiceUtil.log.error("风险报告生成失败:{}", riskReport);
            throw new ServiceException("风险报告生成失败！");
        }
        result.put("oss_path", ossPath);
        return JSON.toJSONString(result);
    }

    //设置商家收入和平台收入
    public void setStoreAmount(TOrderBill bill) {
        Double payAmount = bill.getPayAmount();
        Double settlementRatio = orderMapper.getSettlementRatio(bill.getOrderId());//获取订单结算比例
        double storePrice = ToolUtils.multiply(payAmount, ToolUtils.divideAndCeil(settlementRatio, 100));
        storePrice = ToolUtils.formatDouble2(storePrice);//商家收到的钱
        double platPrice = ToolUtils.subtract(payAmount, storePrice);//平台扣除的钱
        bill.setStoreAmount(storePrice);
        bill.setPlatformAmount(platPrice);
    }

    public TCustomer getAuthByCustomerId(Integer customerid) {
        return customerMapper.getAuthByCustomerId(customerid);//根据客户ID获取授权信息
    }

    /**
     * @Description 获取商家名称
     * @Date 2024/9/21 0:03
     * @Author YWX
     * @Param [storeid]
     * @Return java.lang.String
     **/
    public String getStoreName(Integer storeid) {
        TStore tStore = storeMapper.selectById(storeid);
        if (tStore == null) {
            throw new ServiceException("商家不存在！");
        }
        return tStore.getStorename();
    }

    /**
     * @Description 获取客户认证状态
     * @Date 2024/9/21 16:35
     * @Author YWX
     * @Param [customerId]
     * @Return int
     **/
    public int getCustomerAuth(Integer customerId) {
        int customerAuth = 0;
        Map<String, Object> auth = customerAuthMapper.findByCustomerId(customerId);
        if (auth != null && ToolUtils.isNotEmpty(auth.get("idNumber"))) {
            customerAuth = 1;
        }
        return customerAuth;
    }

    /**
     * @Description 物流信息
     * @Date 2024/9/21 16:36
     * @Author YWX
     * @Param [orderCode, type]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> detailDelivery(String orderCode, Integer type) {
        Map<String, Object> resultMap = orderDeliveryMapper.findByOrderCode(orderCode, type);
        if (resultMap == null) {
            throw new ServiceException("订单还没有发货！");
        }
        if (type.equals(99)) {
            resultMap.put("leaseFixed", 1);
            resultMap.put("acceptTime", resultMap.get("orderCreatetime"));
            return resultMap;
        }
        Object odid = resultMap.get("odid");
        Integer orderStatus = ToolUtils.objToInteger(resultMap.get("orderStatus"));
        List<Map<String, Object>> records;
        if (orderStatus.compareTo(4) >= 0) {
            records = orderDeliveryRecordMapper.listByOdid(odid);
            if (ToolUtils.isListNotEmpty(records)) {//系统有记录，直接返回快递信息
                resultMap.put("records", records);
                int leaseFixed = 0;
                Map<String, Object> map = records.stream().filter(r -> ToolUtils.objToString(r.get("remark")).contains("签收")).findFirst().orElse(null);
                if (map != null) {
                    leaseFixed = 1;
                    Object acceptTime = records.stream().filter(r -> ToolUtils.objToString(r.get("remark")).contains("签收")).findFirst().get().get("acceptTime");
                    resultMap.put("acceptTime", acceptTime);
                }
                resultMap.put("leaseFixed", leaseFixed);
                return resultMap;
            }
        }
        String trackingCode = ToolUtils.objToString(resultMap.get("trackingCode"));
        Integer deliveryType = ToolUtils.objToInteger(resultMap.get("deliveryType"));
        Map<String, Object> map;
        String result;
        int leaseFixed = 0;
        String acceptTime = "";
        try {
            if (deliveryType.equals(1)) {//顺丰
                List<String> trackingNumber = new ArrayList<>();
                trackingNumber.add(trackingCode);
                String checkPhoneNo = ToolUtils.objToString(resultMap.get("checkPhoneNo"));
                result = SfAPIService.checkRoutes(trackingNumber, checkPhoneNo);
            } else {//德邦
                result = DbAPIService.newTraceQuery(trackingCode);
            }
            if (ToolUtils.isEmpty(result)) {
                throw new ServiceException("快递信息查询失败！");
            }
            records = new ArrayList<>();
            map = JSON.parseObject(result, Map.class);
            if (deliveryType.equals(1)) {
                Map<String, Object> apiResultData = JSON.parseObject(map.get("apiResultData").toString(), Map.class);
                if (apiResultData.get("success").equals("false")) {
                    throw new ServiceException(apiResultData.get("errorMsg").toString());
                }
                Map<String, Object> msgData = JSON.parseObject(ToolUtils.objToString(apiResultData.get("msgData")), Map.class);
                if (msgData != null) {
                    List<Map> routeResps = JSON.parseArray(ToolUtils.objToString(msgData.get("routeResps")), Map.class);
                    for (Map routeResp : routeResps) {
                        List<Map> routes = JSON.parseArray(ToolUtils.objToString(routeResp.get("routes")), Map.class);
                        for (Map<String, String> route : routes) {
                            Map<String, Object> record = new HashMap<>();
                            String secondaryStatusName = route.get("secondaryStatusName");//二级状态名称
                            String remark;
                            if (ToolUtils.isNotEmpty(secondaryStatusName)) {
                                remark = secondaryStatusName;
                            } else {
                                remark = SfAPIService.getDeliveryStatus(route.get("opCode"));
                            }
                            if (type.equals(1) && remark.contains("签收")) {
                                leaseFixed = 1;
                                acceptTime = route.get("acceptTime");
                            }
                            record.put("remark", remark);
                            record.put("acceptTime", route.get("acceptTime"));
                            record.put("comm", route.get("acceptAddress") + " " + route.get("remark"));
                            records.add(record);
                        }
                    }
                }
            } else {
                if (map.get("result").equals("false")) {
                    throw new ServiceException(map.get("reason").toString());
                }
                Map<String, Object> responseParam = JSON.parseObject(ToolUtils.objToString(map.get("responseParam")), Map.class);
                if (responseParam != null) {
                    List<Map> traceList = JSON.parseArray(ToolUtils.objToString(responseParam.get("trace_list")), Map.class);
                    for (Map<String, String> route : traceList) {
                        Map<String, Object> record = new HashMap<>();
                        String remark = DbAPIService.getDeliveryStatus(route.get("status"));
                        record.put("remark", remark);
                        record.put("acceptTime", route.get("time"));
                        record.put("comm", route.get("city") + route.get("site") + route.get("description"));
                        records.add(record);
                    }
                }
            }
            if (ToolUtils.isListNotEmpty(records)) {
                orderDeliveryRecordMapper.insertBatch(records, odid);
            }

            //records按照acceptTime倒叙排序
            resultMap.put("records", records.stream().sorted((o1, o2) -> ToolUtils.objToString(o2.get("acceptTime")).compareTo(ToolUtils.objToString(o1.get("acceptTime")))).collect(Collectors.toList()));
            resultMap.put("leaseFixed", leaseFixed);
            resultMap.put("acceptTime", acceptTime);
            return resultMap;
        } catch (IOException e) {
            ServiceUtil.log.error("快递查询失败:{}", e.getMessage());
            throw new ServiceException("快递查询失败！");
        }
    }

    /**
     * @Description 取消订单
     * @Date 2024/9/24 22:10
     * @Author YWX
     * @Param [orderId, userId, userName, type(0取消1审核取消)]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void orderCancel(Integer orderId, Integer userId, String userName, Integer type) {
        TOrder order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new ServiceException("未查询到对应的订单表信息！");
        } else if (order.getOrderStatus().equals(7)) {
            throw new ServiceException("订单已取消，请勿重复操作！");
        } else {
            Integer cancelStatus = order.getCancelStatus();
            if (!cancelStatus.equals(0)) {
                if (type.equals(0) && userName.equals("商家") && cancelStatus.equals(1)) {
                    throw new ServiceException("订单已申请取消，请刷新后进行审核！");
                } else if (cancelStatus.compareTo(1) > 0) {
                    throw new ServiceException("订单申请已审核，请刷新后查看！");
                }
            } else if (userName.equals("客户") && order.getControlStatus().equals(1)) {
                throw new ServiceException("请联系商家取消！");
            } else if (userName.equals("客户") && order.getOrderStatus().compareTo(2) > 0) {
                throw new ServiceException("订单已发货，禁止申请取消！");
            }
        }

        String orderCode = order.getOrderCode();
        aliOrderCancle(order);//支付宝订单取消
        //更新订单状态
        TOrder tOrder = new TOrder();
        tOrder.setOrderId(orderId);
        tOrder.setOrderStatus(7);
        tOrder.setCancelStatus(0);
        String comm = userName + "取消订单";
        tOrder.setControlComm(comm);
        orderMapper.updateById(tOrder);

        //订单取消：待处理的审批变为已拒绝
        orderRecordMapper.orderCancel(orderCode, comm);

        if (order.getOrderType().equals(1)) {
            List<TOrderBill> bills = orderBillMapper.listBuyOutBillByOrderPid(orderId);//获取订单的买断账单
            if (ToolUtils.isNotEmpty(bills)) {
                this.cancelBill(bills);
            }
            orderMapper.cancelBuyOutOrder(orderId);//取消买断订单
            //恢复库存
            goodsSpecsMapper.recoverStock(order.getGsid(), order.getNum());
        }

        //添加操作日志
        TOrderLog log = new TOrderLog();
        log.setOrderCode(orderCode);
        log.setLogType("订单取消");
        log.setComm(userName + "取消订单");
        orderLogService.saveOrderLog(log);
    }

    //支付宝订单取消（解冻押金 租金全退 关闭未支付账单）
    public void aliOrderCancle(TOrder order) {
        unfreezeDeposit(order.getOrderCode());//解冻押金

        //退租金
        List<TOrderBill> bills = orderBillMapper.listBillByOrderIdForRefund(order.getOrderId(), 1);
        cancelBill(bills);//处理取消订单的账单

        refundCoupon(order.getOrderId(), order.getCustomerid());

        if (order.getOrderType().equals(1)) {
            AlipayCreate.orderClose(order.getOrderCode(), getOpenIdByCustomerId(order.getCustomerid()));//关闭订单
        }
    }

    //处理取消订单的账单
    public void cancelBill(List<TOrderBill> bills) {
        if (ToolUtils.isListNotEmpty(bills)) {
            for (TOrderBill bill : bills) {
                Integer billStatus = bill.getBillStatus();
                if (billStatus.equals(0)) {//未支付,关闭
                    closeBill(bill.getObid(), bill.getTransactionId());//关闭账单
                } else if (billStatus.equals(1)) {//已支付,退款
                    ((ServiceUtil) AopContext.currentProxy()).orderBillRefund(bill, 32);
                }
            }
        }
    }

    //账单退款
    @Transactional(rollbackFor = Exception.class)
    public void orderBillRefund(TOrderBill bill, Integer childType) {
        AlipayTradeRefundResponse response = AlipayCreate.alipayTradeRefund(bill.getTransactionId(), bill.getTradeNo(), bill.getPayAmount());
        if (response.isSuccess() || response.getSubMsg().contains("交易不存在")) {
            TOrderBill updateBill = new TOrderBill();
            updateBill.setObid(bill.getObid());
            updateBill.setBillStatus(2);
            updateBill.setTradeStatus(2);
            updateBill.setAvailableAmount(0.0);
            updateBill.setSendBackFee(ToolUtils.objToDouble(response.getRefundFee()));
            orderBillMapper.updateById(updateBill);

            if (response.isSuccess() && response.getFundChange().equals("Y")) {
                // 增加租金账户流水
                addAccountBillByTradeNo(bill.getTransactionId(), 2, childType);
            }
        }
    }

    /**
     * @Description 账单部分退款
     * @Date 2024/11/1 23:00
     * @Author YWX
     * @Param [bill, childType]
     * @Return void
     **/
    /*public void orderBillRefund2(TOrderBill bill, Integer childType) {
        AlipayTradeRefundResponse response = AlipayCreate.alipayTradeRefund2(bill.getTransactionId(), bill.getTradeNo(), bill.getSendBackFee());
        if (response.isSuccess()) {
            Double availableAmount = ToolUtils.subtract(bill.getPayAmount(), response.getRefundFee());//可用金额
            int status = 22;
            if (availableAmount.compareTo(0.0) == 0) {
                status = 2;
            }
            String orderCode = bill.getOrderCode();
            Integer orderId = bill.getOrderId();
            Integer storeid = bill.getStoreid();
            TOrderBill updateBill = new TOrderBill();
            updateBill.setObid(bill.getObid());
            updateBill.setBillStatus(status);
            updateBill.setTradeStatus(status);
            updateBill.setAvailableAmount(availableAmount);
            orderBillMapper.updateById(updateBill);

            if (response.getFundChange().equals("Y")) {
                // 增加租金账户流水
                Integer type = 2;
                TAccountBill accountBill = accountBillMapper.findByStoreId(storeid);//根据交易号获取租金账户信息
                if (accountBill != null) {
                    accountBill.setInoutType(type);
                    accountBill.setOrderCode(orderCode);
                    accountBill.setTransactionId(CodeUtil.generateBillSequence());

                    String amount = response.getSendBackFee();
                    accountBill.setChildType(childType);
                    Double settlementRatio = orderMapper.getSettlementRatio(orderId);
                    double storePrice = ToolUtils.multiply(amount, ToolUtils.divideAndCeil(settlementRatio, 100));
                    storePrice = ToolUtils.formatDouble2(storePrice);//商家的钱
                    double platPrice = ToolUtils.subtract(amount, storePrice);//平台的钱
                    accountBill.setAmount(storePrice);
                    accountBill.setPlatformAmount(platPrice);
                    addAccountBill(type, accountBill, childType, storePrice);
                }
            }
        }
    }*/

    //订单退款
    public Double orderBillRefund3(TOrderBill bill, Integer type) {
        AlipayTradeRefundResponse response;
        if (type.equals(1)) {//全额退款
            response = AlipayCreate.alipayTradeRefund(bill.getTransactionId(), bill.getTradeNo(), bill.getPayAmount());
        } else {//部分退款
            response = AlipayCreate.alipayTradeRefund2(bill.getTransactionId(), bill.getTradeNo(), bill.getSendBackFee());
        }
        if (response.isSuccess()) {
            Double availableAmount = ToolUtils.subtract(bill.getPayAmount(), response.getRefundFee());//可用金额
            int status = 22;
            if (availableAmount.compareTo(0.0) == 0) {
                status = 2;
            }
            TOrderBill updateBill = new TOrderBill();
            updateBill.setObid(bill.getObid());
            updateBill.setBillStatus(status);
            updateBill.setTradeStatus(status);
            updateBill.setAvailableAmount(availableAmount);
            updateBill.setSendBackFee(ToolUtils.objToDouble(response.getRefundFee()));
            orderBillMapper.updateById(updateBill);

        } else if (response.getSubMsg().contains("交易不存在")) {
            int status = 2;
            TOrderBill updateBill = new TOrderBill();
            updateBill.setObid(bill.getObid());
            updateBill.setBillStatus(status);
            updateBill.setTradeStatus(status);
            updateBill.setSendBackFee(ToolUtils.objToDouble(response.getRefundFee()));
            orderBillMapper.updateById(updateBill);

        }
        return ToolUtils.objToDouble(response.getSendBackFee());
    }

    // 增加租金账户流水(type：1支付租金 2退款)
    @Transactional(rollbackFor = Exception.class)
    public void addAccountBillByTradeNo(String tradeNo, Integer type, Integer childType) {
        TAccountBill accountBill = accountBillMapper.findByTradeNo(tradeNo, type);//根据交易号获取租金账户信息
        if (accountBill != null) {
            accountBill.setInoutType(type);
            accountBill.setChildType(childType);
            Double amount = accountBill.getAmount();
            addAccountBill(type, accountBill, childType, amount, accountBill.getPlatformAmount(), accountBill.getPayAmount());
        }
    }

    // 增加租金账户流水(type：1支付租金 2退款)指定金额退款
    public void addAccountBillByTradeNo2(String transactionId, Integer type, Integer childType, Double amount) {
        TAccountBill accountBill = accountBillMapper.findByTradeNo(transactionId, type);//根据流水号获取租金账户信息
        if (accountBill != null) {
            accountBill.setInoutType(type);
            accountBill.setChildType(childType);
            if (amount.compareTo(accountBill.getPayAmount()) < 0) {//部分退款
                Double settlementRatio = orderMapper.getSettlementRatio(accountBill.getOrderId());
                double storePrice = ToolUtils.multiply(amount, ToolUtils.divideAndCeil(settlementRatio, 100));
                storePrice = ToolUtils.formatDouble2(storePrice);//商家的钱
                double platPrice = ToolUtils.subtract(amount, storePrice);//平台的钱
                accountBill.setAmount(storePrice);
                accountBill.setPlatformAmount(platPrice);
                addAccountBill(type, accountBill, childType, storePrice, platPrice, amount);
            } else {//全部退款
                addAccountBill(type, accountBill, childType, accountBill.getAmount(), accountBill.getPlatformAmount(), accountBill.getPayAmount());
            }
        }
    }

    //增加平台账户流水(type：1支付租金 2退款)
    private void addPlateFormAccountBill(Integer type, Integer childType, TAccountBill accountBill) {
        //平台
        TAccount p = accountMapper.selectById(1);
        TAccountBill pb = new TAccountBill();
        pb.setAccountId(p.getAccountId());
        pb.setAccountType(p.getAccountType());
        pb.setAmount(accountBill.getPlatformAmount());
        pb.setType(3);
        pb.setChildType(childType);
        pb.setInoutType(type);
        pb.setOrderCode(accountBill.getOrderCode());
        pb.setTransactionId(accountBill.getTransactionId());
        pb.setPeriod(accountBill.getPeriod());
        Double balance = p.getBalance();
        String comm = accountBill.getComm();
        if (type.equals(1)) {
            balance = ToolUtils.add(balance, accountBill.getPlatformAmount());
            if (ToolUtils.isEmpty(comm)) {
                comm = "第" + accountBill.getPeriod() + "期支付租金";
            }
        } else {
            balance = ToolUtils.subtract(balance, accountBill.getPlatformAmount());
            if (ToolUtils.isEmpty(comm)) {
                comm = "第" + accountBill.getPeriod() + "期退款";
            }
        }
        pb.setComm(comm);
        pb.setBalance(balance);
        accountBillMapper.insert(pb);
        p.setBalance(balance);
        accountMapper.updateByAccountId(p);
    }

    // 增加租金账户流水
    public void addAccountBillByOrderCode(String orderCode, Integer storeId, double amount, Integer type, Integer orderId, String billComm) {
        TAccountBill accountBill = accountBillMapper.findByStoreId(storeId);//根据交易号获取租金账户信息
        if (accountBill != null) {
            accountBill.setInoutType(type);
            accountBill.setOrderCode(orderCode);
            accountBill.setTransactionId(CodeUtil.generateBillSequence());
            accountBill.setComm(billComm);

            int childType = 31;
            if (type.equals(2)) {
                childType = 33;
            }
            accountBill.setChildType(childType);
            Double settlementRatio = orderMapper.getSettlementRatio(orderId);
            double storePrice = ToolUtils.multiply(amount, ToolUtils.divideAndCeil(settlementRatio, 100));
            storePrice = ToolUtils.formatDouble2(storePrice);//商家的钱
            double platPrice = ToolUtils.subtract(amount, storePrice);//平台的钱
            accountBill.setAmount(storePrice);
            accountBill.setPlatformAmount(platPrice);
            addAccountBill(type, accountBill, childType, storePrice, platPrice, amount);
        }
    }

    // 增加账户流水
    private void addAccountBill(Integer type, TAccountBill accountBill, Integer childType, double storePrice, double platPrice, Double payAmount) {
        Double balance = accountBill.getBalance();
        String comm = accountBill.getComm();
        if (type.equals(1)) {
            balance = ToolUtils.add(balance, payAmount);
            if (ToolUtils.isEmpty(comm)) {
                comm = "第" + accountBill.getPeriod() + "期支付租金";
            }
        } else {
            balance = ToolUtils.subtract(balance, payAmount);
            if (ToolUtils.isEmpty(comm)) {
                comm = "第" + accountBill.getPeriod() + "期退款";
            }
        }
        accountBill.setAmount(payAmount);
        accountBill.setComm(comm);
        accountBill.setBalance(balance);
        accountBillMapper.insert(accountBill);
        TAccountBill pb = new TAccountBill();
        BeanUtils.copyProperties(accountBill, pb);
        pb.setAbid(null);
        int inoutType;
        if (type.equals(1)) {
            inoutType = 2;
            balance = ToolUtils.subtract(balance, platPrice);
            if (ToolUtils.isEmpty(comm)) {
                comm = "第" + accountBill.getPeriod() + "期支付租金";
            }
        } else {
            inoutType = 1;
            balance = ToolUtils.add(balance, platPrice);
            if (ToolUtils.isEmpty(comm)) {
                comm = "第" + accountBill.getPeriod() + "期退款";
            }
        }
        pb.setAmount(platPrice);
        pb.setInoutType(inoutType);
        pb.setComm(comm);
        pb.setBalance(balance);
        pb.setTradeType(1);
        pb.setChildType(30);
        accountBillMapper.insert(pb);
        TAccount account = new TAccount();
        account.setAccountId(accountBill.getAccountId());
        account.setBalance(balance);
        accountMapper.updateByAccountId(account);
        addPlateFormAccountBill(type, childType, accountBill);//增加平台账户流水(type：1支付租金 2退款)
    }

    //支付宝订单完结（解冻押金 关闭未支付账单）
    public void aliOrderEnd(TOrder order) {
        unfreezeDeposit(order.getOrderCode());//解冻押金

        //关闭未支付账单
        List<TOrderBill> bills = orderBillMapper.listBillByOrderIdForRefund(order.getOrderId(), 0);
        closeBill(bills);//处理结束订单的账单
    }

    //处理结束订单的账单
    public void closeBill(List<TOrderBill> bills) {
        if (ToolUtils.isListNotEmpty(bills)) {
            for (TOrderBill bill : bills) {
                closeBill(bill.getObid(), bill.getTransactionId());//关闭账单
            }
        }
    }

    //关闭账单
    @Async("asyncPoolTaskExecutor")
    public void closeBill(Integer obid, String transactionId) {
        TOrderBill bill = new TOrderBill();
        bill.setObid(obid);
        bill.setTransactionId(transactionId);
        AlipayTradeQueryResponse response = AlipayCreate.alipayTradeQuery(transactionId, null);
        if (!response.isSuccess() || response.getTradeStatus().equals("TRADE_CLOSED")
                || "交易不存在".equals(response.getSubMsg())) {
            bill.setBillStatus(3);
            bill.setTradeStatus(3);
            orderBillMapper.updateById(bill);
        } else {
            AlipayTradeCloseResponse closeResponse = AlipayCreate.alipayTradeClose(transactionId, null);
            if (closeResponse.isSuccess()) {
                bill.setBillStatus(3);
                bill.setTradeStatus(3);
                orderBillMapper.updateById(bill);
            }
        }
    }

    //解冻押金
    public void unfreezeDeposit(String orderCode) {
        AlipayFundAuthOperationDetailQueryResponse response = AlipayCreate.alipayFundAuthOperationDetailQuery(orderCode);//资金授权操作查询
        String orderStatus = response.getOrderStatus();
        if (ToolUtils.isEmpty(orderStatus)) {
            AlipayCreate.alipayFundAuthOperationCancel(orderCode);//资金授权撤销接口
        } else if (!"CLOSED".equals(orderStatus)) {//非关闭状态：授权未完成超时关闭或冻结资金全额解冻
            Double restAmount = ToolUtils.objToDouble(response.getRestAmount());
            if (restAmount.compareTo(0.0) <= 0) {
                return;
            }
            AlipayCreate.alipayFundAuthOrderUnfreeze(response.getAuthNo(), restAmount);//资金授权解冻
        }
    }

    //获取客户信息
    public TCustomer getCustomerById(Integer customerid) {
        TCustomer tCustomer = customerMapper.selectById(customerid);
        if (tCustomer == null) {
            throw new ServiceException("客户不存在！");
        }
        return tCustomer;
    }

    /**
     * @Description 保存客户输入认证信息
     * @Date 2024/9/27 23:13
     * @Author YWX
     * @Param [realName, idNumber]
     * @Return void
     **/
    public void updateCustomerAuth(String realName, String idNumber) {
        Integer customerId = getCustomerId();
        TCustomerAuth auth = new TCustomerAuth();
        auth.setCustomerid(customerId);
        auth.setInRealName(realName.replaceAll(" ", ""));
        auth.setInIdNumber(idNumber.replaceAll(" ", ""));
        customerAuthMapper.saveInAuth(auth);
    }

    /**
     * @Description 根据客户ID获取支付宝唯一用户标识
     * @Date 2024/9/28 0:59
     * @Author YWX
     * @Param [customerid]
     * @Return java.lang.String
     **/
    public String getOpenIdByCustomerId(Integer customerid) {
        String openId = customerMapper.getOpenIdByCustomerId(customerid);
        if (ToolUtils.isEmpty(openId)) {
            throw new ServiceException("支付宝唯一用户标识为空！");
        }
        return openId;
    }

    //设置买断价
    /*public void setBuyPrice(Double rentAfterCoupon, Map<String, Object> result, Double buyPrice) {
        Map<String, Object> set = platformSetMapper.getDetail();
        double storePrice = ToolUtils.multiply(rentAfterCoupon, ToolUtils.divideAndCeil(set.get("settlementRatio"), 100));
        storePrice = ToolUtils.formatDouble2(storePrice);//商家收到的钱
        double platPrice = ToolUtils.subtract(rentAfterCoupon, storePrice);//平台扣除的钱
        result.put("buyPrice", buyPrice);//原始买断价
        buyPrice = ToolUtils.subtract(buyPrice, storePrice);
        if (buyPrice.compareTo(0.0) < 0) {
            buyPrice = 0.0;
        }
        result.put("buyPriceAfterStore", buyPrice);//实际支付买断价=买断价-商家收到的钱（扣除平台收的钱）
        result.put("platPrice", platPrice);
        result.put("storePrice", storePrice);
    }*/

    //获取申请买断买断价
    public double getBuyPriceAfterStore(List<TOrderBill> bills, Double buyPrice) {
        /*double storeAmount = 0;
        LocalDateTime beginTime = null;
        LocalDateTime endTime = null;
        for (int i = 0; i < bills.size(); i++) {
            TOrderBill bill = bills.get(i);
            Integer billStatus = bill.getBillStatus();
            if (i == 0) {
                if (!billStatus.equals(1)) {
                    break;
                }
                beginTime = bill.getBeginTime();
            }
            if (billStatus.equals(1)) {
                endTime = bill.getEndTime();
                storeAmount = ToolUtils.add(storeAmount, bill.getStoreAmount());
            }
        }
        if (ToolUtils.isNotEmpty(beginTime) && ToolUtils.isNotEmpty(endTime)) {
            int day = ToolUtils.getDaysBetween(beginTime, endTime);
            if (day > 365) {//买断价=(1+renewal_rate%)*买断价
                Map<String, Object> set = platformSetMapper.getDetail();
                buyPrice = ToolUtils.multiply(buyPrice, ToolUtils.add(1.0, ToolUtils.divideAndCeil(set.get("renewal_rate"), 100)));
            }
        }

        return ToolUtils.subtract(buyPrice, storeAmount);*/
        double billAmount = 0.0;
        for (TOrderBill bill : bills) {
            Integer billStatus = bill.getBillStatus();
            if (ToolUtils.payStatusBuyout.contains(billStatus)) {
                billAmount = ToolUtils.add(billAmount, bill.getPayAmount());
            }
        }
        return ServiceUtil.getBuyPrice(buyPrice, billAmount);
    }

    //获取买断价
    public static double getBuyPrice(Double buyPrice, double billAmount) {
        double buyPriceAfterStore;
        if (buyPrice.compareTo(billAmount) < 0) {//买断价小于总租金，则到期买断价=0
            buyPriceAfterStore = 0.0;
        } else {//到期买断价=签约价（买断价）-总租金
            buyPriceAfterStore = ToolUtils.subtract(buyPrice, billAmount);
        }
        return buyPriceAfterStore;
    }

    //获取实付金额
    public static double getPayAmount(List<TOrderBill> bills) {
        double payAmount = 0;
        for (TOrderBill bill : bills) {
            Integer billStatus = bill.getBillStatus();
            if (ToolUtils.payStatusBuyout.contains(billStatus)) {
                payAmount = ToolUtils.add(payAmount, bill.getPayAmount());
            }
        }
        return payAmount;
    }

    //获取用户信息
    public TUser getUser() {
        TUser user = tUserMapper.selectById(getUserId());
        if (user == null) {
            throw new ServiceException("用户不存在！");
        }
        return user;
    }

    /**
     * @Description 添加租赁合同
     * @Date 2024/10/4 22:17
     * @Author YWX
     * @Param [tOrder, goodsName, gsName, idNumber]
     * @Return void
     **/
    @Async("asyncPoolTaskExecutor")
    public void saveOrderContract(TOrder tOrder, List<TOrderBill> bills, String goodsName, String gsName, TCustomer tCustomer, Integer type, RequestAttributes requestAttributes) {
        // 恢复请求上下文
        RequestContextHolder.setRequestAttributes(requestAttributes, true);
        String idNumber = tCustomer.getIdNumber();
        if (ToolUtils.isEmpty(idNumber)) {
            return;
        }
        //未启用e签宝合同不生成
        if (!ConfigKey.enabled) {
            return;
        }
        //租赁合同
        Map<String, String> storeMap = storeMapper.getLegalNameAndAddress(tOrder.getStoreid());
        String storeSeal = storeMap.get("storeSeal");
        if (ToolUtils.isEmpty(storeSeal)) {
            storeSeal = updateStoreSeal(storeMap.get("businessName"), tOrder.getStoreid());
            storeMap.put("storeSeal", storeSeal);
        }
        String customerseal = tCustomer.getCustomerseal();
        if (ToolUtils.isEmpty(customerseal)) {
            customerseal = updateCustomerSeal(tCustomer.getRealName(), tOrder.getCustomerid());
        }
        storeMap.put("idNumber", idNumber);
        storeMap.put("customerseal", customerseal);
        storeMap.put("goodsName", goodsName);
        storeMap.put("gsName", gsName);
        storeMap.put("realName", tCustomer.getRealName());
        //TOrderContract orderContract = eqbService.getContractUrl(tOrder, bills, storeMap);
        String pdfPath;
        if (type.equals(2)) {
            pdfPath = uploadPdfToOss(FileUtils.generateRenewContractHtml(tOrder, storeMap), 2);
        } else {
            pdfPath = uploadPdfToOss(FileUtils.generateLeaseContractHtml(tOrder, bills, storeMap), 2);
        }

        eqbService.getContractUrl2(pdfPath, tOrder.getOrderCode(), tOrder.getOrderId(), type, requestAttributes);
    }

    //根据客户ID查询客户认证信息
    public Map<String, Object> findCustomerAuthByCustomerId(Integer customerid) {
        return customerAuthMapper.findByCustomerId(customerid);
    }

    //更新客户输入认证状态
    public void updateCustomerAuthById(Integer caid, Integer inCustomerAuth) {
        TCustomerAuth customerAuth = new TCustomerAuth();
        customerAuth.setCaid(caid);
        customerAuth.setInCustomerAuth(inCustomerAuth);
        customerAuthMapper.updateById(customerAuth);
    }

    //更新客户身份证信息
    public void updateCustomerIdNumberById(Integer customerid, String inRealName, String inIdNumber) {
        TCustomer customer = new TCustomer();
        customer.setCustomerid(customerid);
        customer.setRealName(inRealName);
        customer.setIdNumber(inIdNumber);
        customerMapper.updateById(customer);
    }

    //更新商家印章
    public String updateStoreSeal(String legalPersonName, Integer storeid) {
        String imgPath = CustomSealUtil.generateEntSeal(legalPersonName, ConfigKey.pdfpath);
        String jfQsq = OssService.uploadBtFile(imgPath, "seal/store/" + legalPersonName + ".png");
        FileUtils.deleteFile(imgPath);
        tStoreDetailMapper.updateStoreSeal(storeid, jfQsq);
        return jfQsq;
    }

    //更新客户印章
    public String updateCustomerSeal(String username, Integer customerid) {
        String imgPath = PersonalSealUtil.seal(username, 1, 1, ConfigKey.pdfpath);
        String yfQsq = OssService.uploadBtFile(imgPath, "seal/customer/" + username + ".png");
        FileUtils.deleteFile(imgPath);
        customerMapper.updateCustomerSeal(customerid, yfQsq);
        return yfQsq;
    }

    //设置续租金额
    public List<TOrderBill> setBillPrice(TOrderBill bill, Integer couponid, Integer used) {
        TOrderBill lastBill = orderBillMapper.findLastBillByOrderId(bill.getOrderId());
        Double billAmount = lastBill.getOldAmount();
        LocalDateTime endTime = lastBill.getEndTime();
        if (!bill.getEndTime().isAfter(endTime)) {
            throw new ServiceException("续租结束时间必须大于上次账单结束时间！");
        }
        bill.setRenewBill(1);
        LocalDateTime realEnd = bill.getEndTime();
        LocalDateTime beginTime = lastBill.getBeginTime();
        Integer day1 = ToolUtils.getDaysBetween(beginTime, endTime);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        Integer day2 = ToolUtils.getDaysBetween(endTime, realEnd);
        //day2是day1的整数倍，续租金额=租金*倍数
        int multiple = day2 / 30;
        int remainder = day2 % 30;
        Integer period = lastBill.getPeriod();
        double dayRent = ToolUtils.divideAndCeil(billAmount, day1);//每天的租金
        Double billAmount30;
        if (day1.equals(30)) {
            billAmount30 = billAmount;
        } else {
            billAmount30 = ToolUtils.multiply(dayRent, 30);
        }
        bill.setBillAmount(billAmount30);
        bill.setOldAmount(bill.getBillAmount());
        bill.setPayAmount(billAmount30);
        this.setStoreAmount(bill);
        bill.setStageNo(lastBill.getStageNo() + 1);
        List<TOrderBill> bills = new ArrayList<>();
        LocalDateTime newBeginTime = endTime;
        LocalDateTime newEndTime = endTime.plusDays(30);
        double totalAmount = 0.0;
        for (int i = 0; i < multiple; i++) {
            TOrderBill newBill = new TOrderBill();
            BeanUtils.copyProperties(bill, newBill);
            newBill.setTransactionId(CodeUtil.generateBillSequence());
            period++;
            newBill.setPeriod(period);
            newBill.setOldPeriod(period);
            if (i > 0) {
                newBeginTime = newEndTime.plusDays(1);
                newEndTime = newEndTime.plusDays(30);
            }
            //如果newBeginTime的秒是59则加1秒
            if (newBeginTime.getSecond() == 59) {
                newBeginTime = newBeginTime.plusSeconds(1);
            }
            //如果newBeginTime的秒是0则减1秒
            if (newEndTime.getSecond() == 0) {
                newEndTime = newEndTime.minusSeconds(1);
            }
            String planDate = newBeginTime.minusDays(1).format(formatter);
            newBill.setBeginTime(newBeginTime);
            newBill.setPlanDate(planDate);
            newBill.setEndTime(newEndTime);
            bills.add(newBill);
            totalAmount = ToolUtils.add(totalAmount, newBill.getPayAmount());
        }
        if (remainder > 0) {
            TOrderBill newBill = new TOrderBill();
            BeanUtils.copyProperties(bill, newBill);
            newBill.setTransactionId(CodeUtil.generateBillSequence());
            Double newBillAmount = ToolUtils.multiply(dayRent, remainder);//续租金额
            newBill.setBillAmount(newBillAmount);
            newBill.setOldAmount(newBill.getBillAmount());
            newBill.setPayAmount(newBillAmount);//续租实付金额
            this.setStoreAmount(newBill);
            period++;
            newBill.setPeriod(period);
            newBill.setOldPeriod(period);
            if (day2.compareTo(30) < 0) {
                newEndTime = endTime.plusDays(remainder);
            } else {
                newEndTime = newEndTime.plusDays(remainder);
            }

            //如果newEndTime的秒是0则减1秒
            if (newEndTime.getSecond() == 0) {
                newEndTime = newEndTime.minusSeconds(1);
            }
            newBeginTime = getNewBeginTime(newEndTime, remainder);

            String planDate = newBeginTime.minusDays(1).format(formatter);
            newBill.setBeginTime(newBeginTime);
            newBill.setPlanDate(planDate);
            newBill.setEndTime(newEndTime);
            bills.add(newBill);
            totalAmount = ToolUtils.add(totalAmount, newBill.getPayAmount());
        }

        Double price = totalAmount;
        Integer periods = bills.size();
        Double rentFirst = bills.get(0).getBillAmount();
        Double rentLeft = 0.0;
        if (periods > 1) {
            rentLeft = bills.get(1).getBillAmount();
        }
        Double goodsPrice = lastBill.getBuyPrice();
        Integer customerid = lastBill.getCustomerid();
        TCoupon coupon = null;
        if (ToolUtils.isTrueInteger(couponid)) {//用户选择了优惠券
            coupon = tCouponMapper.getUseCouponByCouponIdAndCustomerId(couponid, customerid);
            coupon = checkCouponDay(day2, coupon);
        } else {//用户未选择优惠券
            Double money = 0.0;//最高金额
            List<TCoupon> coupons = tCustomerCouponMapper.listCustomerCoupon(customerid, lastBill.getGoodsId(), 2);//客户已领商品券列表
            if (ToolUtils.isListNotEmpty(coupons)) {
                for (TCoupon tCoupon : coupons) {
                    if (checkCouponDay(day2, tCoupon) == null) {
                        continue;
                    }
                    Double limitMoney = tCoupon.getLimitMoney();
                    Integer couponType = tCoupon.getCouponType();//优惠券类型（1首期优惠券2其它期优惠券3总租金券）
                    Integer category = tCoupon.getCategory();//优惠券品类（1抵扣券2折扣券3特价券）
                    Double useMoney = tCoupon.getMoney();
                    Integer useCondition = tCoupon.getUseCondition();//使用条件（1签约价值2总租金3月租金）
                    boolean sq = rentFirst.compareTo(limitMoney) >= 0.0;//首期优惠券是否满足首期租金条件
                    boolean qtq = rentLeft.compareTo(limitMoney) >= 0.0;//其他期优惠券是否满足首期租金条件
                    boolean qyj = useCondition.equals(1) && limitMoney.compareTo(goodsPrice) <= 0;//签约价
                    boolean zzj = useCondition.equals(2) && limitMoney.compareTo(price) <= 0;//总租金
                    Integer belongType = tCoupon.getBelongType();
                    Double ceilingAmount = tCoupon.getCeilingAmount();
                    boolean isCeiling = belongType.equals(2) && ceilingAmount != null;
                    if (couponType.equals(1) && (qyj || zzj || (useCondition.equals(3) && rentFirst.compareTo(limitMoney) >= 0)) && limitMoney.compareTo(money) > 0) {//使用满减券，且满足使用条件
                        if (category.equals(2)) {
                            money = ToolUtils.multiply(rentFirst, ToolUtils.divideAndCeil(useMoney, 10));
                            if (isCeiling && money.compareTo(ceilingAmount) > 0) {
                                money = ceilingAmount;
                            }
                        } else {
                            money = useMoney;
                        }
                        coupon = tCoupon;
                    } else if (couponType.equals(2) && (qyj || zzj || (useCondition.equals(3) && rentLeft.compareTo(limitMoney) >= 0)) && limitMoney.compareTo(money) > 0) {//使用满减券，且满足使用条件
                        if (category.equals(2)) {
                            money = ToolUtils.multiply(ToolUtils.multiply(rentLeft, ToolUtils.divideAndCeil(useMoney, 10)), periods - 1);
                            if (isCeiling && money.compareTo(ceilingAmount) > 0) {
                                money = ceilingAmount;
                            }
                        } else {
                            money = ToolUtils.multiply(useMoney, periods - 1);
                        }
                        coupon = tCoupon;
                    } else if (couponType.equals(3) && useCondition.equals(2) && price.compareTo(limitMoney) >= 0 && limitMoney.compareTo(money) > 0) {//使用满减券，且满足使用条件
                        if (category.equals(2)) {
                            money = ToolUtils.multiply(price, ToolUtils.divideAndCeil(useMoney, 10));
                            if (isCeiling && money.compareTo(ceilingAmount) > 0) {
                                money = ceilingAmount;
                            }
                        } else {
                            money = useMoney;
                        }
                        coupon = tCoupon;
                    }
                }
            }
        }

        if (coupon != null) {
            Double couponPrice = 0.0;
            Double rentFirstAfterCoupon = rentFirst;
            Double rentLeftAfterCoupon = rentLeft;
            Double rentAfterCoupon = price;//优惠后租金,默认为总租金
            Double limitMoney = coupon.getLimitMoney();
            Integer couponType = coupon.getCouponType();//优惠券类型（1首期优惠券2其它期优惠券3总租金券）
            Integer category = coupon.getCategory();//优惠券品类（1抵扣券2折扣券3特价券）
            Double useMoney = coupon.getMoney();
            Integer useCondition = coupon.getUseCondition();//使用条件（1签约价值2总租金3月租金）
            boolean sq = rentFirst.compareTo(limitMoney) >= 0.0;//首期优惠券是否满足首期租金条件
            boolean qtq = rentLeft.compareTo(limitMoney) >= 0.0;//其他期优惠券是否满足首期租金条件
            if (couponType.equals(1)) {//使用首期优惠券
                if (category.equals(2)) {
                    couponPrice = ToolUtils.multiply(rentFirst, ToolUtils.divideAndCeil(useMoney, 10));
                } else if (category.equals(3)) {
                    couponPrice = ToolUtils.subtract(rentFirst, useMoney);
                } else {
                    couponPrice = useMoney;
                }
                rentFirstAfterCoupon = ToolUtils.subtract(rentFirst, couponPrice);//优惠后首期租金
            } else if (couponType.equals(2)) {//使用其它期优惠券
                if (category.equals(2)) {
                    rentLeftAfterCoupon = ToolUtils.subtract(rentLeft, ToolUtils.divideAndCeil(useMoney, 10));//优惠后剩余租期租金
                } else if (category.equals(3)) {
                    rentLeftAfterCoupon = useMoney;
                } else {
                    rentLeftAfterCoupon = ToolUtils.subtract(rentLeft, useMoney);//优惠后剩余租期租金
                }
            } else if (couponType.equals(3)) {//总租金券
                if (category.equals(2)) {
                    couponPrice = ToolUtils.multiply(price, ToolUtils.divideAndCeil(useMoney, 10));
                    couponPrice = getCouponPrice(coupon, couponPrice);
                } else if (category.equals(3)) {
                    couponPrice = ToolUtils.subtract(price, useMoney);
                } else {
                    couponPrice = useMoney;
                }
                if (periods.equals(1)) {//如果租期为1，则首期租金为优惠后租金
                    rentFirstAfterCoupon = ToolUtils.subtract(rentFirst, couponPrice);//优惠后首期租金
                } else {
                    rentAfterCoupon = ToolUtils.subtract(price, couponPrice);
                    rentLeftAfterCoupon = ToolUtils.divideAndCeilDown(rentAfterCoupon, periods);//剩余租期每期租金
                    rentFirstAfterCoupon = ToolUtils.subtract(rentAfterCoupon, ToolUtils.multiply(rentLeftAfterCoupon, periods - 1));//首期租金=总租金-剩余租期租金*（租期-1）
                }
            }
            couponid = coupon.getCouponid();

            totalAmount = 0.0;
            for (int i = 0; i < bills.size(); i++) {
                TOrderBill ob = bills.get(i);
                if (i == 0) {
                    ob.setPayAmount(rentFirstAfterCoupon);
                    setStoreAmount(ob);
                } else if (ob.getPayAmount().compareTo(rentLeftAfterCoupon) > 0) {
                    ob.setPayAmount(rentLeftAfterCoupon);
                    setStoreAmount(ob);
                }
                totalAmount = ToolUtils.add(totalAmount, ob.getPayAmount());
            }

            if (used.equals(1)) {
                useCoupon(couponid, coupon.getVoucherCode(), lastBill.getOrderId(), customerid, totalAmount);
            }
        }

        bill.setPayAmount(totalAmount);
        int installmentNo = 0;
        for (TOrderBill orderBill : bills) {
            orderBill.setInstallmentNo(installmentNo + 1);
        }
        return bills;
    }

    //设置续租金额（输入续租金额与计算的金额不一致）
    public List<TOrderBill> setBillPrice2(TOrderBill bill, Double rent, Double inRent) {
        TOrderBill lastBill = orderBillMapper.findLastBillByOrderId(bill.getOrderId());
        Double billAmount = lastBill.getOldAmount();
        LocalDateTime endTime = lastBill.getEndTime();
        LocalDateTime realEnd = bill.getEndTime();
        if (!realEnd.isAfter(endTime)) {
            throw new ServiceException("续租结束时间必须大于上次账单结束时间！");
        }
        bill.setRenewBill(1);
        LocalDateTime beginTime = lastBill.getBeginTime();
        Integer day1 = ToolUtils.getDaysBetween(beginTime, endTime);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        Integer day2 = ToolUtils.getDaysBetween(endTime, realEnd);
        //day2是day1的整数倍，续租金额=租金*倍数
        int multiple = day2 / 30;
        int remainder = day2 % 30;
        Integer period = lastBill.getPeriod();
        double dayRent1 = ToolUtils.divideAndCeil(billAmount, day1);//每天的租金
        double dayRent = ToolUtils.divideAndCeil(inRent, day2);//每天的租金
        Double billAmount30;
        Double oldAmount30;
        if (day1.equals(30)) {
            oldAmount30 = billAmount;
        } else {
            oldAmount30 = ToolUtils.multiply(dayRent1, 30);
        }
        if (day2.equals(30)) {
            billAmount30 = inRent;
        } else {
            billAmount30 = ToolUtils.multiply(dayRent, 30);
        }
        bill.setBillAmount(billAmount30);
        bill.setOldAmount(oldAmount30);
        bill.setPayAmount(billAmount30);
        this.setStoreAmount(bill);
        bill.setStageNo(lastBill.getStageNo() + 1);
        List<TOrderBill> bills = new ArrayList<>();
        LocalDateTime newBeginTime = endTime;
        LocalDateTime newEndTime = endTime.plusDays(30);
        double totalAmount = 0.0;
        for (int i = 0; i < multiple; i++) {
            TOrderBill newBill = new TOrderBill();
            BeanUtils.copyProperties(bill, newBill);
            newBill.setTransactionId(CodeUtil.generateBillSequence());
            period++;
            newBill.setPeriod(period);
            newBill.setOldPeriod(period);
            if (i > 0) {
                newBeginTime = newEndTime.plusDays(1);
                newEndTime = newEndTime.plusDays(30);
            }
            //如果newBeginTime的秒是59则加1秒
            if (newBeginTime.getSecond() == 59) {
                newBeginTime = newBeginTime.plusSeconds(1);
            }
            //如果newBeginTime的秒是0则减1秒
            if (newEndTime.getSecond() == 0) {
                newEndTime = newEndTime.minusSeconds(1);
            }
            String planDate = newBeginTime.minusDays(1).format(formatter);
            newBill.setBeginTime(newBeginTime);
            newBill.setPlanDate(planDate);
            newBill.setEndTime(newEndTime);
            bills.add(newBill);
            totalAmount = ToolUtils.add(totalAmount, newBill.getPayAmount());
        }
        if (remainder > 0) {
            TOrderBill newBill = new TOrderBill();
            BeanUtils.copyProperties(bill, newBill);
            newBill.setTransactionId(CodeUtil.generateBillSequence());
            Double newBillAmount = ToolUtils.subtract(inRent, totalAmount);//续租金额
            newBill.setBillAmount(newBillAmount);
            newBill.setOldAmount(ToolUtils.multiply(dayRent1, remainder));
            newBill.setPayAmount(newBillAmount);//续租实付金额
            this.setStoreAmount(newBill);
            period++;
            newBill.setPeriod(period);
            newBill.setOldPeriod(period);
            if (day2.compareTo(30) < 0) {
                newEndTime = endTime.plusDays(remainder);
            } else {
                newEndTime = newEndTime.plusDays(remainder);
            }

            //如果newEndTime的秒是0则减1秒
            if (newEndTime.getSecond() == 0) {
                newEndTime = newEndTime.minusSeconds(1);
            }
            newBeginTime = getNewBeginTime(newEndTime, remainder);

            String planDate = newBeginTime.minusDays(1).format(formatter);
            newBill.setBeginTime(newBeginTime);
            newBill.setPlanDate(planDate);
            newBill.setEndTime(newEndTime);
            bills.add(newBill);
            totalAmount = ToolUtils.add(totalAmount, newBill.getPayAmount());
        }

        bill.setPayAmount(totalAmount);
        int installmentNo = 0;
        for (TOrderBill orderBill : bills) {
            orderBill.setInstallmentNo(installmentNo + 1);
        }
        return bills;
    }

    //校验优惠券天数和价格
    public static Map checkCouponDayAndPrice(Map coupon, Integer day, Double price, Double rentFirst, Double rentLeft, Double buyPrice, Double goodsPrice, Integer periods) {
        Double limitMoney = ToolUtils.objToDouble(coupon.get("limitMoney"));
        Integer couponType = ToolUtils.objToInteger(coupon.get("couponType"));//优惠券类型（1首期优惠券2其它期优惠券3总租金券）
        Integer category = ToolUtils.objToInteger(coupon.get("category"));//优惠券品类（1抵扣券2折扣券3特价券）
        Double useMoney = ToolUtils.objToDouble(coupon.get("useMoney"));
        Integer useCondition = ToolUtils.objToInteger(coupon.get("useCondition"));//使用条件（1签约价值2总租金3月租金）
        boolean sq = rentFirst.compareTo(limitMoney) >= 0.0;//首期优惠券是否满足首期租金条件
        boolean qtq = rentLeft.compareTo(limitMoney) >= 0.0;//其他期优惠券是否满足首期租金条件
        boolean qyj = useCondition.equals(1) && limitMoney.compareTo(goodsPrice) <= 0;//签约价
        boolean zzj = useCondition.equals(2) && limitMoney.compareTo(price) <= 0;//总租金
        Integer belongType = ToolUtils.objToInteger(coupon.get("belongType"));
        Double ceilingAmount = ToolUtils.objToDouble(coupon.get("ceilingAmount"));
        boolean isCeiling = belongType.equals(2) && ceilingAmount != null;
        boolean isUse = false;//优惠券是否可用
        if (couponType.equals(1) && (qyj || zzj || (useCondition.equals(3) && rentFirst.compareTo(limitMoney) >= 0))) {//使用满减券，且满足使用条件
            isUse = true;
        } else if (couponType.equals(2) && (qyj || zzj || (useCondition.equals(3) && rentLeft.compareTo(limitMoney) >= 0))) {//使用满减券，且满足使用条件
            isUse = true;
        } else if (couponType.equals(3) && useCondition.equals(2) && price.compareTo(limitMoney) >= 0) {//使用满减券，且满足使用条件
            isUse = true;
        }
        if (!isUse) {
            return null;
        }
        Integer symbolType = ToolUtils.objToInteger(coupon.get("symbolType"));//符号类型（1大于等于X天 2小于等于X天 3等于X天 4大于等于X天且小于等于Y天 5小于等于X天或大于等于Y天）
        if (symbolType.equals(0)) return coupon;
        Integer xday = ToolUtils.objToInteger(coupon.get("xday"));
        Integer yday = ToolUtils.objToInteger(coupon.get("yday"));
        if ((symbolType.equals(1) && day.compareTo(xday) < 0)
                || (symbolType.equals(2) && day.compareTo(xday) > 0)
                || (symbolType.equals(3) && day.compareTo(xday) != 0)
                || (symbolType.equals(4) && (day.compareTo(xday) < 0 || day.compareTo(yday) > 0))
                || (symbolType.equals(5) && (day.compareTo(xday) > 0 || day.compareTo(yday) < 0))) {
            coupon = null;
        }
        return coupon;
    }

    //校验优惠券天数
    public static TCoupon checkCouponDay(Integer day, TCoupon coupon) {
        if (coupon == null) {
            return null;
        }
        Integer symbolType = coupon.getSymbolType();//符号类型（1大于等于X天 2小于等于X天 3等于X天 4大于等于X天且小于等于Y天 5小于等于X天或大于等于Y天）
        if (symbolType.equals(0)) return coupon;
        Integer xday = coupon.getXday();
        Integer yday = coupon.getYday();
        if ((symbolType.equals(1) && day.compareTo(xday) < 0)
                || (symbolType.equals(2) && day.compareTo(xday) > 0)
                || (symbolType.equals(3) && day.compareTo(xday) != 0)
                || (symbolType.equals(4) && (day.compareTo(xday) < 0 || day.compareTo(yday) > 0))
                || (symbolType.equals(5) && (day.compareTo(xday) > 0 || day.compareTo(yday) < 0))) {
            coupon = null;
        }
        return coupon;
    }

    public static Double getCouponPrice(TCoupon coupon, Double couponPrice) {
        Integer belongType = coupon.getBelongType();
        Double ceilingAmount = coupon.getCeilingAmount();
        boolean isCeiling = belongType.equals(2) && ceilingAmount != null;
        if (isCeiling && couponPrice.compareTo(ceilingAmount) > 0) {
            couponPrice = ceilingAmount;
        }
        return couponPrice;
    }

    //使用优惠券
    public void useCoupon(Integer couponid, String voucherCode, Integer orderId, Integer customerId, Object totalFee) {
        if (ToolUtils.isTrueInteger(couponid)) {
            TOrderCoupon orderCoupon = new TOrderCoupon();
            orderCoupon.setOrderId(orderId);
            orderCoupon.setCouponid(couponid);
            Map<String, String> coupon = tCouponMapper.getUseCouponByCouponId(couponid);
            String activityId = coupon.get("activityId");
            if (ToolUtils.isNotEmpty(activityId)) {
                if (ToolUtils.isEmpty(voucherCode)) {
                    throw new ServiceException("没有券码可用！");
                }
                String outBizNo = CodeUtil.generateOuterOrderNo();
                orderCoupon.setOutBizNo(outBizNo);
                orderCoupon.setActivityId(activityId);
                coupon.put("outBizNo", outBizNo);
                coupon.put("totalFee", ToolUtils.objToString(totalFee));
                coupon.put("voucherCode", voucherCode);
                AlipayCreate.useCoupon(coupon);
                tCouponCodeMapper.updateUsedByVoucherCode(voucherCode, 1);
                orderCoupon.setVoucherCode(voucherCode);
            }
            tOrderCouponMapper.insert(orderCoupon);
            tCustomerCouponMapper.useCoupon(couponid, customerId);//使用优惠券
        }
    }

    //取消券核销状态
    public void refundCoupon(Integer orderId, Integer customerId) {
        List<Map> coupons = tOrderCouponMapper.listCouponIdByOrderId(orderId);//根据订单id获取优惠券IDS
        if (ToolUtils.isListNotEmpty(coupons)) {
            for (Map<String, String> coupon : coupons) {
                if (ToolUtils.isNotEmpty(coupon.get("activityId"))) {
                    String voucherCode = coupon.get("voucherCode");
                    AlipayCreate.refundCoupon(coupon);
                    tCouponCodeMapper.updateUsedByVoucherCode(voucherCode, 0);
                }
                tCustomerCouponMapper.cancelCoupon(ToolUtils.objToInteger(coupon.get("couponid")), customerId, LocalDateTime.now());//取消订单的优惠券
            }
        }
    }

    //同步商家券券码
    public void syncCoupon(String activityId) {
        TCoupon coupon = tCouponMapper.findByActivityId(activityId);//根据活动id获取优惠券信息
        Integer couponid = coupon.getCouponid();
        List<String> voucherCodes = tCouponCodeMapper.listCouponCodeByCouponId(couponid);
        Integer num = coupon.getNum();
        int index = 0;
        if (ToolUtils.isListNotEmpty(voucherCodes)) {
            index = voucherCodes.size() - 1;
        }
        String couponCode = coupon.getCouponCode() + "_";
        List<TCouponCode> couponCodes = new ArrayList<>();
        for (int i = index; i < num; i++) {
            String voucherCode = couponCode + ToolUtils.getUuid();
            voucherCodes.add(voucherCode);
            TCouponCode cc = new TCouponCode();
            cc.setCouponid(couponid);
            cc.setVoucherCode(voucherCode);
            couponCodes.add(cc);
        }
        //voucherCodes超过1000条时分批次执行
        int size = 1000;
        for (int i = 0; i < voucherCodes.size(); i += size) {
            List<String> subList = voucherCodes.subList(i, Math.min(i + size, voucherCodes.size()));
            AlipayCreate.syncCoupon(activityId, subList);
        }
        AlipayCreate.modifyCouponNum(activityId, num);

        if (ToolUtils.isListNotEmpty(couponCodes)) {
            tCouponCodeMapper.insertBatchSomeColumn(couponCodes);
        }

    }

    //计算续租开始时间
    private LocalDateTime getNewBeginTime(LocalDateTime newEndTime, int remainder) {
        LocalDateTime newBeginTime;
        LocalDateTime endDateTime = newEndTime.toLocalDate().atTime(00, 00, 00);
        if (remainder == 1) {
            newBeginTime = endDateTime;
        } else {
            newBeginTime = endDateTime.minusDays(remainder - 1);
        }
        return newBeginTime;
    }

    //获取订单合同数量
    public int getContractNumByOrderId(Integer orderId) {
        return orderContractMapper.getContractNumByOrderId(orderId);
    }

    //保存客户领取支付宝券信息
    public void addCustomerCoupon(String activityId, String openId, String voucherCode, String eventTime) {
        Integer customerId = customerMapper.getCustomerIdByOpenid(openId);
        if (ToolUtils.isTrueInteger(customerId)) {
            TCoupon coupon = tCouponMapper.findByActivityId(activityId);//根据活动id获取优惠券信息
            TCustomerCoupon cc = new TCustomerCoupon();
            cc.setCouponid(coupon.getCouponid());
            cc.setCustomerid(customerId);
            cc.setVoucherCode(voucherCode);
            //修改数据
            LocalDateTime begin;
            LocalDateTime end;
            if (coupon.getLimitType().equals(1)) {//相对期限
                begin = ToolUtils.timestampToDateTime(eventTime);
                end = begin.plusDays(coupon.getLimitDay());
            } else {
                begin = coupon.getUseTimeBegin();
                end = coupon.getUseTimeEnd();
            }
            cc.setBeginDate(begin);
            cc.setEndDate(end);
            cc.setCreateid(customerId);
            cc.setCreatetime(LocalDateTime.now());
            tCustomerCouponMapper.insert(cc);
        }
    }

    //修改订单（买家续租、买断、订单租金发生变化、扣款时间变化、租期结束时间变化）
    public void orderModify(Integer orderId, String orderCode, Integer customerid, TOrderLog log) {
        try {
            List<TOrderBill> bills2 = orderBillMapper.listBillForSyncByOrderId(orderId);
            AlipayCreate.orderModify(orderCode, getOpenIdByCustomerId(customerid), bills2);
        } catch (Exception e) {
            log.setComm(log.getComm() + ";订单修改失败：" + e.getMessage());
            throw new RuntimeException(e);
        } finally {
            orderLogService.saveOrderLog(log);
        }
    }
}
